Solving 10385 - Duathlon (Ternary search)
[andmenj-acm.git] / 11367 - Full tank? / 11367.3.cpp
blob2cb111bb8cecc8756d84a772c9a07af22179ff1f
1 /*
2 Accepted
3 */
4 #include <iostream>
5 #include <vector>
6 #include <queue>
7 //#include <cassert>
9 using namespace std;
11 const int MAXN = 1000, MAXC = 100;
13 struct edge{
14 int i, g, w;
15 edge(){}
16 edge(int I, int G, int W) : i(I), g(G), w(W) {}
17 bool operator < (const edge &that) const {
18 return w > that.w;
22 int p[MAXN], d[MAXN][MAXC+1], n;
23 vector<edge> g[MAXN];
26 int dijkstra(const int &start, const int &end, const int &c){
27 for (int i=0; i<n; ++i)
28 for (int j=0; j<=c; ++j)
29 d[i][j] = INT_MAX;
31 priority_queue<edge> q;
32 q.push(edge(start, 0, 0));
33 d[start][0] = 0;
35 while (q.size()){
36 edge u = q.top();
37 q.pop();
39 //printf("popped <%d, %d, %d>\n", u.i, u.g, u.w);
40 if (u.i == end){
41 return u.w;
43 if (d[u.i][u.g] < u.w) continue;
45 //I can buy another gallon and stay where I am
46 if (u.g < c && u.w + p[u.i] < d[u.i][u.g+1]){
47 d[u.i][u.g+1] = u.w + p[u.i];
48 q.push(edge(u.i, u.g+1, u.w + p[u.i]));
51 //Now try to reach each other node as long as I have enough gas
52 vector<edge> &v = g[u.i];
53 for (int j=0; j<v.size(); ++j){
54 int distance = v[j].w;
55 int neighbor = v[j].i;
56 if (u.g >= distance){
57 int new_gas = u.g - distance;
58 if (u.w < d[neighbor][new_gas]){
59 d[neighbor][new_gas] = u.w;
60 q.push(edge(neighbor, new_gas, u.w));
65 return INT_MAX;
69 int main(){
70 int m;
71 scanf("%d %d", &n, &m);
72 for (int i=0; i<n; ++i){
73 scanf("%d", &p[i]);
76 while (m--){
77 int u, v, d;
78 scanf("%d %d %d", &u, &v, &d);
79 g[u].push_back(edge(v, 0, d));
80 g[v].push_back(edge(u, 0, d));
83 int q;
84 scanf("%d", &q);
85 while (q--){
86 int c, s, e;
87 scanf("%d %d %d", &c, &s, &e);
88 int t = dijkstra(s, e, c);
89 if (t < INT_MAX){
90 printf("%d\n", t);
91 }else{
92 printf("impossible\n");
95 return 0;